/**
 * Project Name:b2c-app
 * File Name:PayController.java
 * Package Name:cn.bluemobi.app.controller.consume
 * Date:2016年2月2日上午10:37:59
 * Copyright (c) 2016, bluemobi.cn All Rights Reserved.
 *
 */

package cn.bluemobi.app.controller.pay;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.bluemobi.app.core.controller.AppBaseController;
import cn.bluemobi.app.core.utils.PropertiesUtils;
import cn.bluemobi.app.entity.form.PayInfoForm;
import cn.bluemobi.app.entity.output.PayInfo;
import cn.bluemobi.app.service.PayService;
import cn.bluemobi.app.utils.unionPay.sdk.AcpService;
import cn.bluemobi.app.utils.wechatPay.WechatPayUtil;
import cn.bluemobi.common.core.dto.Dto;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;

/**
 * Description: 支付 <br/>
 * Date: 2016年2月2日 上午10:37:59 <br/>
 * 
 * @author hut
 * @version
 * @see
 */
@Controller
@RequestMapping("/pay")
@Api(description = "支付", value = "pay")
public class PayController extends AppBaseController {

	protected static final Logger log = LogManager
			.getLogger(PayController.class);

	@Autowired
	private PayService payService;

	/**
	 * 获取支付信息
	 */
	@RequestMapping(value = "/getPayInfo")
	@ApiOperation(value = "获取支付信息", httpMethod = "POST")
	@ResponseBody
	public Dto<PayInfo> getPayInfo(
			@ApiParam("会员ID") @RequestParam("memberId") String memberId,
			@ApiParam("支付参数json") @RequestBody PayInfoForm payInfoForm,
			HttpServletRequest request) {
		return payService.getPayInfo(memberId, payInfoForm,
				getRemortIP(request), "APP");
	}

	/**
	 * 支付宝异步回调方法
	 * 
	 * @throws AlipayApiException
	 * 
	 * 
	 */
	@RequestMapping("/alipayNotify/{batchNo}")
	@ApiOperation(value = "支付宝回调", httpMethod = "POST")
	public void alipayNotify(HttpServletRequest request,
			HttpServletResponse response, @PathVariable String batchNo)
			throws AlipayApiException {
		log.info("进入支付宝支付回调");
		log.info("支付编号为：" + batchNo);
		Map<String, String[]> requestParams = request.getParameterMap();
		Map<String, String> params = new HashMap<>();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter
				.hasNext();) {
			String name = (String) iter.next();
			String[] values = requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}
		log.info("支付宝回调参数:" + params.toString());
		String status = params.get("trade_status");
		String type = params.remove("sign_type");
		Boolean signVerified = AlipaySignature.rsaCheckV2(params,
				PropertiesUtils.getProperty("ALI_PUBLIC_KEY"), "UTF-8", type);
		log.info("验证签名结果:" + signVerified);
		if (signVerified) {
			log.info("status" + status.toLowerCase());
			if (StringUtils.equals(status.toLowerCase(), "trade_success")) {
				payService.changePaySuccess(batchNo, "1", params);
				try {
					response.getWriter().write("success");
				} catch (IOException e) {
					log.error(ExceptionUtils.getMessage(e));
				}
			} else if (StringUtils.equals(status.toLowerCase(),
					"trade_finished")) {
				try {
					response.getWriter().write("success");
				} catch (IOException e) {
					log.error(ExceptionUtils.getMessage(e));
				}
			}
		} else {
			log.error("参数验证失败");
		}
	}

	/**
	 * 微信支付成功回调函数
	 */
	@RequestMapping("/wechatPayNotify/{batchNo}")
	@ApiOperation(value = "微信支付成功回调函数", httpMethod = "POST")
	public void wechatPaySuccess(HttpServletRequest request,
			HttpServletResponse response, @PathVariable String batchNo)
			throws IOException {
		log.info("进入微信支付回调，回调订单号：" + batchNo);
		BufferedReader r = request.getReader();
		String inputLine = "";
		StringBuilder xml = new StringBuilder();
		try {
			while ((inputLine = r.readLine()) != null) {
				xml.append(inputLine);
			}
			Map<String, String> map = WechatPayUtil.doXMLParse(xml.toString());
			if (!WechatPayUtil.validateSign(map)) {
				log.error("验证签名失败");
			} else {
				if (StringUtils.equals(map.get("result_code"), "SUCCESS")) {
					payService.changePaySuccess(batchNo, "2", map);
				} else {
					log.info("微信支付失败,result_code:" + map.get("result_code"));
				}
				response.getWriter()
						.write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");
			}
		} catch (Exception e) {
		}
	}

	/**
	 * 银联支付成功回调函数
	 */
	@ApiOperation(value = "银联支付成功回调函数", httpMethod = "POST")
	@RequestMapping("/unionPayNotify/{batchNo}")
	public void unionPaySuccess(HttpServletRequest request,
			HttpServletResponse response, @PathVariable String batchNo)
			throws IOException, ServletException {
		log.info("进入银联支付回调，回调订单号：" + batchNo);
		Map<String, String> reqParam = getAllRequestParam(request);
		log.info("返回参数:" + reqParam.toString());
		// 验证签名
		if (!AcpService.validate(reqParam, "UTF-8")) {
			log.info("验证签名结果[失败].");
		} else {
			log.info("验证签名结果[成功]. 处理订单");
			if (StringUtils.equals("00", reqParam.get("respCode"))
					|| StringUtils.equals("A6", reqParam.get("respCode"))) {
				payService.changePaySuccess(batchNo, "3", reqParam);
			} else {
				log.error("银联支付失败。");
			}
		}
		log.info("银联支付接收后台通知结束");
	}

	private Map<String, String> getAllRequestParam(
			final HttpServletRequest request) {
		Map<String, String> res = new HashMap<>();
		Enumeration<?> temp = request.getParameterNames();
		if (null != temp) {
			while (temp.hasMoreElements()) {
				String en = (String) temp.nextElement();
				String value = request.getParameter(en);
				res.put(en, value);
				// 在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
				// System.out.println("ServletUtil类247行 temp数据的键=="+en+"
				// 值==="+value);
				if (null == res.get(en) || "".equals(res.get(en))) {
					res.remove(en);
				}
			}
		}
		return res;
	}

	@ApiOperation(value = "测试回调", httpMethod = "POST")
	@RequestMapping("/testChangePaySuccess")
	@ResponseBody
	public Dto<Object> testChangePaySuccess(
			@ApiParam("支付编号") @RequestParam("batchNo") String batchNo,
			@ApiParam("支付类型（ 1支付宝，2微信 ）") @RequestParam("payType") String payType) {
		Map<String, String> params = new HashMap<String, String>();
		params.put("total_amount", "30");
		payService.changePaySuccess(batchNo, payType, params);
		return Dto.SUCCESS;
	}
}
